package com.woniuxy.pxxt.shiro;


import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SessionStorageEvaluator;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.mgt.DefaultWebSessionStorageEvaluator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: ideaAdmin
 * TODO: Class
 * TODO: 配置shiro的文件
 * Date: 2022/2/23:15:53
 * Description:
 */
@Configuration
public class ShiroConfig {
    /**
     * Author ideaAdmin
     * TODO: 配置securityManager 需要使用自定义的JWT方式进行认证
     * Date 15:55 2022/2/23
     * * @param myRealm   需要注入的自定义类
     * * @return org.apache.shiro.mgt.DefaultWebSecurityManager 注册成bean
     **/
    @Bean
    public DefaultWebSecurityManager securityManager(MyRealm myRealm) {
        //处理底层无法转换自定义的MyJsonWebToken
        myRealm.setAuthenticationTokenClass(MyJsonWebToken.class);


        return new DefaultWebSecurityManager(myRealm);
    }

    /**
     * Author ideaAdmin
     * TODO: 配置过滤器工厂 设置过滤器链  使自定义的过滤器生效
     * Date 17:02 2022/2/23
     * * @param defaultSecurityManager
     * * @return org.apache.shiro.spring.web.ShiroFilterFactoryBean
     **/
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultSecurityManager defaultSecurityManager) {

        //创建过滤器工厂bean
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //设置securityManager
        shiroFilterFactoryBean.setSecurityManager(defaultSecurityManager);


        Map<String, Filter> filterMap = new HashMap<>();
        filterMap.put("JWT",new JWTFilter());
        //把自定义过滤器返回给过滤器工厂来管理
        shiroFilterFactoryBean.setFilters(filterMap);


        //设置过滤器链 从上到下顺序执行

        Map<String, String> filterChainDefinitionMap = new HashMap<>();

        //filterChainDefinitionMap.put("/**","anon");
        filterChainDefinitionMap.put("/**","JWT");

        filterChainDefinitionMap.put("/course/**","anon");

        //表示匿名用户可以直接访问这个login/**的方法
        filterChainDefinitionMap.put("/user/login","anon");
        filterChainDefinitionMap.put("/captcha","anon");

        // /401的请求也是匿名访问
        filterChainDefinitionMap.put("/401","anon");

        //设置过滤器过滤的条件
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return shiroFilterFactoryBean;
    }


    /**
     * 禁用session, 不保存用户登录状态。保证每次请求都重新认证。
     * 需要注意的是，如果用户代码里调用Subject.getSession()还是可以用session
     */
    @Bean
    protected SessionStorageEvaluator sessionStorageEvaluator() {
        DefaultWebSessionStorageEvaluator sessionStorageEvaluator = new DefaultWebSessionStorageEvaluator();
        sessionStorageEvaluator.setSessionStorageEnabled(false);
        return sessionStorageEvaluator;
    }
    //开启shiro注解支持
    @Bean
    public AuthorizationAttributeSourceAdvisor
    authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new
                AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }
    /**
     * Description : 管理Subject主体对象,生命周期的组件,用户只是打印下生产销毁日志什么的,请参考spring中bean的生命周期   <br/>
     * ChangeLog : 1. 创建 (2021/4/27 0:25 [mayuhang]);
     *
     * @return org.apache.shiro.spring.LifecycleBeanPostProcessor
     **/
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }


}
